/*
 * Copyright (C) 2016 huanghaibin_dev <huanghaibin_dev@163.com>
 * WebSite https://github.com/MiracleTimes-Dev
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.talkweb.calendarview;


import ohos.agp.animation.Animator;
import ohos.agp.animation.AnimatorProperty;
import ohos.agp.components.*;
import ohos.agp.render.Canvas;
import ohos.app.Context;
import ohos.global.config.ConfigManager;
import ohos.global.configuration.Configuration;
import ohos.multimodalinput.event.MmiPoint;
import ohos.multimodalinput.event.TouchEvent;
import org.jetbrains.annotations.Nullable;


/**
 * 日历布局
 */
@SuppressWarnings("unused")
public class CalendarLayout extends DirectionalLayout implements Component.EstimateSizeListener, Component.TouchEventListener, Component.BindStateChangedListener {

    /**
     * 多点触控支持
     */
    private int mActivePointerId;

    private static final int ACTIVE_POINTER = 1;

    private static final int INVALID_POINTER = -1;

    /**
     * 周月视图
     */
    private static final int CALENDAR_SHOW_MODE_BOTH_MONTH_WEEK_VIEW = 0;


    /**
     * 仅周视图
     */
    private static final int CALENDAR_SHOW_MODE_ONLY_WEEK_VIEW = 1;

    /**
     * 仅月视图
     */
    private static final int CALENDAR_SHOW_MODE_ONLY_MONTH_VIEW = 2;

    /**
     * 默认展开
     */
    private static final int STATUS_EXPAND = 0;

    /**
     * 默认收缩
     */
    private static final int STATUS_SHRINK = 1;

    /**
     * 默认状态
     */
    private int mDefaultStatus;

    private boolean isWeekView;

    /**
     * 星期栏
     */
    WeekBar mWeekBar;

    /**
     * 自定义ViewPager，月视图
     */
    MonthViewPager mMonthView;

    /**
     * 日历
     */
    CalendarView mCalendarView;

    /**
     * 自定义的周视图
     */
    WeekViewPager mWeekPager;

    /**
     * 年视图
     */
    YearViewPager mYearView;

    /**
     * ContentView
     */
    ComponentContainer mContentView;

    /**
     * 默认手势
     */
    private static final int GESTURE_MODE_DEFAULT = 0;

    private static final int defaultToutchThreshold = 10;

//       /**
    //     * 仅日历有效
    //     */
//    private static final int GESTURE_MODE_ONLY_CALENDAR = 1;

    /**
     * 禁用手势
     */
    private static final int GESTURE_MODE_DISABLED = 2;

    /**
     * 手势模式
     */
    private int mGestureMode;


    private int mCalendarShowMode;

    private int mContentViewTranslateY; //ContentView  可滑动的最大距离距离 , 固定
    private int mViewPagerTranslateY = 0;// ViewPager可以平移的距离，不代表mMonthView的平移距离

    private float downY;
    private float mLastY;
    private float mLastX;
    private boolean isAnimating;

    /**
     * 内容布局id
     */
    private int mContentViewId;

    /**
     * 手速判断
     */
    private VelocityDetector mVelocityTracker;

    private int mMaximumVelocity;

    private int mItemHeight;

    private CalendarViewDelegate mDelegate;

    public CalendarLayout(Context context, AttrSet attrs) {
        super(context, attrs);
        setOrientation(DirectionalLayout.VERTICAL);
        mContentViewId = AttrSetUtils.getInt(attrs, AttrSetContant.calendar_content_view_id, 0);
        mDefaultStatus = AttrSetUtils.getInt(attrs, AttrSetContant.default_status, STATUS_EXPAND);
        mCalendarShowMode = AttrSetUtils.getInt(attrs, AttrSetContant.calendar_show_mode, CALENDAR_SHOW_MODE_BOTH_MONTH_WEEK_VIEW);
        mGestureMode = AttrSetUtils.getInt(attrs, AttrSetContant.gesture_mode, GESTURE_MODE_DEFAULT);
        mVelocityTracker = VelocityDetector.obtainInstance();
        //final ViewConfiguration configuration = ViewConfiguration.get(context);
        //int mTouchSlop = configuration.getScaledTouchSlop();

//        mMaximumVelocity = configuration.getScaledMaximumFlingVelocity();
        mMaximumVelocity = 1000;

//        addDrawTask(this);
        setEstimateSizeListener(this);
        setTouchEventListener(this);
        setBindStateChangedListener(this);
    }

    /**
     * 初始化
     *
     * @param delegate delegate
     */
    final void setup(CalendarViewDelegate delegate) {
        this.mDelegate = delegate;
        mItemHeight = mDelegate.getCalendarItemHeight();
        initCalendarPosition(delegate.mSelectedCalendar.isAvailable() ?
                delegate.mSelectedCalendar :
                delegate.createCurrentDate());
        updateContentViewTranslateY();
    }

    /**
     * 初始化当前时间的位置
     *
     * @param cur 当前日期时间
     */
    private void initCalendarPosition(Calendar cur) {
        int diff = CalendarUtil.getMonthViewStartDiff(cur, mDelegate.getWeekStart());
        int size = diff + cur.getDay() - 1;
        updateSelectPosition(size);
    }

    /**
     * 当前第几项被选中，更新平移量
     *
     * @param selectPosition 月视图被点击的position
     */
    final void updateSelectPosition(int selectPosition) {
        int line = (selectPosition + 7) / 7;
        mViewPagerTranslateY = (line - 1) * mItemHeight;
    }

    /**
     * 设置选中的周，更新位置
     *
     * @param week week
     */
    final void updateSelectWeek(int week) {
        mViewPagerTranslateY = (week - 1) * mItemHeight;
    }


    /**
     * 更新内容ContentView可平移的最大距离
     */
    void updateContentViewTranslateY() {
        Calendar calendar = mDelegate.mIndexCalendar;
        if (mDelegate.getMonthViewShowMode() == CalendarViewDelegate.MODE_ALL_MONTH) {
            mContentViewTranslateY = 5 * mItemHeight;
        } else {
            mContentViewTranslateY = CalendarUtil.getMonthViewHeight(calendar.getYear(),
                    calendar.getMonth(), mItemHeight, mDelegate.getWeekStart())
                    - mItemHeight;
        }
        //已经显示周视图，则需要动态平移contentView的高度
        if (mWeekPager.getVisibility() == VISIBLE) {
            if (mContentView == null)
                return;
            mContentView.setTranslationY(-mContentViewTranslateY);
        }
    }

    /**
     * 更新日历项高度
     */
    final void updateCalendarItemHeight() {
        mItemHeight = mDelegate.getCalendarItemHeight();
        if (mContentView == null)
            return;
        Calendar calendar = mDelegate.mIndexCalendar;
        updateSelectWeek(CalendarUtil.getWeekFromDayInMonth(calendar, mDelegate.getWeekStart()));
        if (mDelegate.getMonthViewShowMode() == CalendarViewDelegate.MODE_ALL_MONTH) {
            mContentViewTranslateY = 5 * mItemHeight;
        } else {
            mContentViewTranslateY = CalendarUtil.getMonthViewHeight(calendar.getYear(), calendar.getMonth(),
                    mItemHeight, mDelegate.getWeekStart()) - mItemHeight;
        }
        translationViewPager();
        if (mWeekPager.getVisibility() == VISIBLE) {
            mContentView.setTranslationY(-mContentViewTranslateY);
        }
    }

    /**
     * 隐藏日历
     */
    public void hideCalendarView() {
        if (mCalendarView == null) {
            return;
        }
        mCalendarView.setVisibility(Component.HIDE);
        if (!isExpand()) {
            expand(0);
        }

//        requestLayout();
        invalidate();
    }

    /**
     * 显示日历
     */
    public void showCalendarView() {

        mCalendarView.setVisibility(VISIBLE);
//        requestLayout();
        invalidate();
    }

    public boolean onTouchEvent(Component component, TouchEvent event) {
        if (mContentView == null) {
            return false;
        }
        MmiPoint mmiPoint = event.getPointerPosition(0);
        int action = event.getAction();
        float y = mmiPoint.getY();
        float x = mmiPoint.getX();
        mVelocityTracker.addEvent(event);
        switch (action) {
            //down和up的y值比move的y值少129，推测该值为状态栏高度
            case TouchEvent.PRIMARY_POINT_DOWN:
                mLastY = downY = y;
                mLastX = x;
                System.out.println("DOWN: " + x + "," + y);
                break;
            case TouchEvent.POINT_MOVE:
                float dy = y - downY - 129;
                float dx = x - mLastX;
                System.out.println("MOVE:" + x + "," + y);
                if (Math.abs(dy) < defaultToutchThreshold ||
                        Math.abs(dy) - Math.abs(dx) < 0) {
                    System.out.println("横向滑动 POINT_MOVE");
                    return false;
                }
                //向上滑动，并且contentView平移到最大距离，显示周视图
                if (dy < 0 && mContentView.getTranslationY() == -mContentViewTranslateY) {
                    mWeekPager.setVisibility(VISIBLE);
                    mMonthView.setVisibility(INVISIBLE);
                    if (!isWeekView && mDelegate.mViewChangeListener != null) {
                        mDelegate.mViewChangeListener.onViewChange(false);
                    }
                    isWeekView = true;
                    return true;
                }

                //向下滑动，并且contentView已经完全平移到底部
                if (dy > 0 && mContentView.getTranslationY() + dy >= 0) {
                    mContentView.setTranslationY(0);
                    translationViewPager();
                    return true;
                }

                //向上滑动，并且contentView已经平移到最大距离，则contentView平移到最大的距离
                if (dy < 0 && mContentView.getTranslationY() + dy <= -mContentViewTranslateY) {
                    mContentView.setTranslationY(-mContentViewTranslateY);
                    translationViewPager();
                    return true;
                }

                hideWeek(false);

                //否则按比例平移
                mContentView.setTranslationY(mContentView.getTranslationY() + dy);
                translationViewPager();
                break;
            case TouchEvent.PRIMARY_POINT_UP:
                float diffX = x - mLastX;
                float diffY = y - downY;
                System.out.println("UP:" + x + "," + y);
                if ((Math.abs(diffY) < defaultToutchThreshold &&
                        Math.abs(diffX) < defaultToutchThreshold) ||
                        Math.abs(diffY) - Math.abs(diffX) < 0) {
                    System.out.println("拦截 up" + diffX + "," + diffY);
                    return false;
                }
                //System.out.println("PRIMARY_POINT_UP");
                //units： 1：pix/ms  1000: pix/s
                mVelocityTracker.calculateCurrentVelocity(1000, 0, mMaximumVelocity);
                float mYVelocity = mVelocityTracker.getVerticalVelocity();

                //速度超过1000pix/ms
                System.out.println("mYVelocity: " + mYVelocity);
                if (Math.abs(mYVelocity) >= mMaximumVelocity) {
                    if (mYVelocity < 0) {
                        shrink();
                    } else {
                        expand();
                    }
                    return true;
                }

                if (diffY > 0) {
                    //向下滑动
                    if (Math.abs(diffY) > 100) {
                        expand();
                        System.out.println("向下滑动 expand " + diffY);
                    } else {
                        shrink();
                        System.out.println("向下滑动 shrink " + diffY);
                    }
                } else {
                    //向上滑动
                    if (Math.abs(diffY) > 100) {
                        shrink();
                        System.out.println("向上滑动 shrink " + diffY);
                    } else {
                        expand();
                        System.out.println("向上滑动 expand " + diffY);
                    }
                }
                break;
        }

        return true;
    }

    private int getPointerIndex(TouchEvent ev, int id) {
        int activePointerIndex = ev.getPointerId(id);
        if (activePointerIndex == -1) {
            mActivePointerId = INVALID_POINTER;
        }
        return activePointerIndex;
    }

    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        if (mContentView == null || mCalendarView == null) {
            return;
        }

        int year = mDelegate.mIndexCalendar.getYear();
        int month = mDelegate.mIndexCalendar.getMonth();
        int weekBarHeight = CalendarUtil.dipToPx(getContext(), 1)
                + mDelegate.getWeekBarHeight();

        int monthHeight = CalendarUtil.getMonthViewHeight(year, month,
                mDelegate.getCalendarItemHeight(),
                mDelegate.getWeekStart(),
                mDelegate.getMonthViewShowMode())
                + weekBarHeight;

        int height = EstimateSpec.getSize(heightMeasureSpec);


        if (mDelegate.isFullScreenCalendar()) {
            mContentView.setHeight(monthHeight);
            mContentView.invalidate();
            return;
        }
        if (monthHeight >= height && mMonthView.getHeight() > 0) {
            height = monthHeight;
        } else if (monthHeight < height && mMonthView.getHeight() > 0) {

        }

        int h;
        if (mCalendarShowMode == CALENDAR_SHOW_MODE_ONLY_MONTH_VIEW ||
                mCalendarView.getVisibility() == HIDE) {
            h = height - (mCalendarView.getVisibility() == HIDE ? 0 : mCalendarView.getHeight());
        } else if (mGestureMode == GESTURE_MODE_DISABLED && !isAnimating) {
            if (isExpand()) {
                h = height - monthHeight;
            } else {
                h = height - weekBarHeight - mItemHeight;
            }
        } else {
            h = height - weekBarHeight - mItemHeight;
        }

//        mContentView.setHeight(h);
        mContentView.invalidate();
    }

    /**
     * 平移ViewPager月视图
     */
    private void translationViewPager() {
        float percent = mContentView.getTranslationY() * 1.0f / mContentViewTranslateY;
        mMonthView.setTranslationY(mViewPagerTranslateY * percent);
    }

    public void setModeBothMonthWeekView() {
        mCalendarShowMode = CALENDAR_SHOW_MODE_BOTH_MONTH_WEEK_VIEW;
        invalidate();
    }

    public void setModeOnlyWeekView() {
        mCalendarShowMode = CALENDAR_SHOW_MODE_ONLY_WEEK_VIEW;
        invalidate();
    }

    public void setModeOnlyMonthView() {
        mCalendarShowMode = CALENDAR_SHOW_MODE_ONLY_MONTH_VIEW;
        invalidate();
    }

    /**
     * 是否展开了
     *
     * @return isExpand
     */
    public final boolean isExpand() {
        return mMonthView.getVisibility() == VISIBLE;
    }

    /**
     * 是否展开了
     *
     * @return isExpand
     */
    public final boolean isShrink() {
        return mWeekPager.getVisibility() == VISIBLE;
    }


    public boolean expand() {
        return expand(240);
    }


    /**
     * 展开
     *
     * @param duration 时长
     * @return 展开是否成功
     */
    public boolean expand(int duration) {
        if (isAnimating ||
                mCalendarShowMode == CALENDAR_SHOW_MODE_ONLY_WEEK_VIEW ||
                mContentView == null) {
            return false;
        }
        if (mMonthView.getVisibility() != VISIBLE) {
            mWeekPager.setVisibility(HIDE);
            onShowMonthView();
            isWeekView = false;
            mMonthView.setVisibility(VISIBLE);
        }

        AnimatorProperty animatorProperty = mContentView.createAnimatorProperty();
        animatorProperty.setDuration(duration)
                .setLoopedCount(0)
                .moveToY(mContentView.getTop())
                .setStateChangedListener(new Animator.StateChangedListener() {
                    @Override
                    public void onStart(Animator animator) {
                        isAnimating = true;
                        System.out.println("expand onStart:" + isAnimating);
                    }

                    @Override
                    public void onStop(Animator animator) {

                    }

                    @Override
                    public void onCancel(Animator animator) {

                    }

                    @Override
                    public void onEnd(Animator animator) {
                        isAnimating = false;
                        System.out.println("expand onEnd:" + isAnimating);
                        if (mGestureMode == GESTURE_MODE_DISABLED) {
                            invalidate();
                        }

                        hideWeek(true);
                        mMonthView.setTranslationY(0);
                        if (mDelegate.mViewChangeListener != null && isWeekView) {
                            mDelegate.mViewChangeListener.onViewChange(true);
                        }
                        isWeekView = false;
                    }

                    @Override
                    public void onPause(Animator animator) {

                    }

                    @Override
                    public void onResume(Animator animator) {

                    }
                }).start();
        return true;
    }

    public boolean shrink() {
        return shrink(240);
    }

    /**
     * 收缩
     *
     * @param duration 时长
     * @return 成功或者失败
     */
    public boolean shrink(int duration) {
        if (mGestureMode == GESTURE_MODE_DISABLED) {
            invalidate();
        }
        if (isShrink() || isAnimating || mContentView == null) {
            return false;
        }

        AnimatorProperty animatorProperty = mContentView.createAnimatorProperty();
        animatorProperty.setDuration(duration)
                .setLoopedCount(0)
                .moveFromY(mContentView.getPivotX())
                .moveToY(mWeekPager.getHeight() + mWeekBar.getBottom())
                .setStateChangedListener(new Animator.StateChangedListener() {
                    @Override
                    public void onStart(Animator animator) {
                        isAnimating = true;
                        System.out.println("shrink onStart:" + isAnimating);
                    }

                    @Override
                    public void onStop(Animator animator) {
                        isAnimating = false;
                        System.out.println("shrink onstop:" + isAnimating);
                        showWeek();
                        isWeekView = true;
                    }

                    @Override
                    public void onCancel(Animator animator) {

                    }

                    @Override
                    public void onEnd(Animator animator) {

                    }

                    @Override
                    public void onPause(Animator animator) {

                    }

                    @Override
                    public void onResume(Animator animator) {

                    }
                }).start();
        return true;
    }

    /**
     * 初始化状态
     */
    final void initStatus() {

        if ((mDefaultStatus == STATUS_SHRINK ||
                mCalendarShowMode == CALENDAR_SHOW_MODE_ONLY_WEEK_VIEW) &&
                mCalendarShowMode != CALENDAR_SHOW_MODE_ONLY_MONTH_VIEW) {
            if (mContentView == null) {
                mWeekPager.setVisibility(VISIBLE);
                mMonthView.setVisibility(HIDE);
                return;
            }

            getContext().getUITaskDispatcher().asyncDispatch(new Runnable() {
                @Override
                public void run() {
                    AnimatorProperty animatorProperty = mContentView.createAnimatorProperty();
                    animatorProperty.setDuration(0)
                            .setLoopedCount(0)
                            .moveFromY(mContentView.getTranslationY())
                            .moveToY(-mContentViewTranslateY)
                            .setStateChangedListener(new Animator.StateChangedListener() {
                                @Override
                                public void onStart(Animator animator) {
                                    isAnimating = true;
                                    System.out.println("initStatus onStart:" + isAnimating);
                                }

                                @Override
                                public void onStop(Animator animator) {
                                    isAnimating = false;
                                    System.out.println("initStatus onStop:" + isAnimating);
                                    isWeekView = true;
                                    showWeek();
                                    if (mDelegate == null || mDelegate.mViewChangeListener == null) {
                                        return;
                                    }
                                    mDelegate.mViewChangeListener.onViewChange(false);
                                }

                                @Override
                                public void onCancel(Animator animator) {

                                }

                                @Override
                                public void onEnd(Animator animator) {

                                }

                                @Override
                                public void onPause(Animator animator) {

                                }

                                @Override
                                public void onResume(Animator animator) {

                                }
                            }).start();
                }
            });
        } else {
            if (mDelegate.mViewChangeListener == null) {
                return;
            }
            getContext().getUITaskDispatcher().asyncDispatch(new Runnable() {
                @Override
                public void run() {
                    mDelegate.mViewChangeListener.onViewChange(true);
                }
            });
        }
    }

    /**
     * 隐藏周视图
     */
    private void hideWeek(boolean isNotify) {
        if (isNotify) {
            onShowMonthView();
        }
        mWeekPager.setVisibility(HIDE);
        mMonthView.setVisibility(VISIBLE);
    }

    /**
     * 显示周视图
     */
    private void showWeek() {
        onShowWeekView();
        if (mWeekPager != null && mWeekPager.getProvider() != null) {
            mWeekPager.getProvider().notifyDataChanged();
            mWeekPager.setVisibility(VISIBLE);
        }
        mMonthView.setVisibility(INVISIBLE);
    }

    /**
     * 周视图显示事件
     */
    private void onShowWeekView() {
        if (mWeekPager.getVisibility() == VISIBLE) {
            return;
        }
        if (mDelegate != null && mDelegate.mViewChangeListener != null && !isWeekView) {
            mDelegate.mViewChangeListener.onViewChange(false);
        }
    }


    /**
     * 周视图显示事件
     */
    private void onShowMonthView() {
        if (mMonthView.getVisibility() == VISIBLE) {
            return;
        }
        if (mDelegate != null && mDelegate.mViewChangeListener != null && isWeekView) {
            mDelegate.mViewChangeListener.onViewChange(true);
        }
    }

    /**
     * ContentView是否滚动到顶部 如果完全不适合，就复写这个方法
     *
     * @return 是否滚动到顶部
     */
    protected boolean isScrollTop() {
        if (mContentView instanceof CalendarScrollView) {
            return ((CalendarScrollView) mContentView).isScrollToTop();
        }
        if (mContentView instanceof ListContainer) {
            return ((ListContainer) mContentView).getContentStartOffset() == 0;
        }
        /*if (mContentView instanceof AbsListView) {
            boolean result = false;
            AbsListView listView = (AbsListView) mContentView;
            if (listView.getFirstVisiblePosition() == 0) {
                final View topChildView = listView.getChildAt(0);
                result = topChildView.getTop() == 0;
            }
            return result;
        }*/

        return mContentView.getScrollValue(Component.VERTICAL) == 0;
    }


    /**
     * 隐藏内容布局
     */
    final void hideContentView() {
        if (mContentView == null) {
            return;
        }

        AnimatorProperty animatorProperty = mContentView.createAnimatorProperty();
        animatorProperty.setDuration(200)
                .setLoopedCount(0)
                //.moveFromY(getHeight())
                .moveToY(getHeight() - mMonthView.getHeight())
                .setStateChangedListener(new Animator.StateChangedListener() {
                    @Override
                    public void onStart(Animator animator) {
                    }

                    @Override
                    public void onStop(Animator animator) {
                        mContentView.setVisibility(INVISIBLE);
                    }

                    @Override
                    public void onCancel(Animator animator) {

                    }

                    @Override
                    public void onEnd(Animator animator) {

                    }

                    @Override
                    public void onPause(Animator animator) {

                    }

                    @Override
                    public void onResume(Animator animator) {

                    }
                }).start();
    }

    /**
     * 显示内容布局
     */
    final void showContentView() {
        if (mContentView == null) {
            return;
        }
        //mContentView.setTranslationY(getHeight() - mMonthView.getHeight());
        mContentView.setVisibility(VISIBLE);

        AnimatorProperty animatorProperty = mContentView.createAnimatorProperty();
        animatorProperty.setDuration(200)
                .setLoopedCount(0)
                //.moveFromY(getScrollValue(Component.VERTICAL))
                .moveToY(mContentView.getTop())
                .start();
    }

    private int getCalendarViewHeight() {
        return mMonthView.getVisibility() == VISIBLE ? mDelegate.getWeekBarHeight() + mMonthView.getHeight() :
                mDelegate.getWeekBarHeight() + mDelegate.getCalendarItemHeight();
    }


    @Override
    public boolean onEstimateSize(int widthMeasureSpec, int heightMeasureSpec) {
        if (mContentView == null || mCalendarView == null) {
            return false;
        }

        if (!(mContentView instanceof ListContainer || mContentView instanceof ScrollView)) {
            return false;
        }

        int year = mDelegate.mIndexCalendar.getYear();
        int month = mDelegate.mIndexCalendar.getMonth();
        int weekBarHeight = CalendarUtil.dipToPx(getContext(), 1)
                + mDelegate.getWeekBarHeight();

        int monthHeight = CalendarUtil.getMonthViewHeight(year, month,
                mDelegate.getCalendarItemHeight(),
                mDelegate.getWeekStart(),
                mDelegate.getMonthViewShowMode())
                + weekBarHeight;

        int height = EstimateSpec.getSize(heightMeasureSpec);

        if (mDelegate.isFullScreenCalendar()) {
            int heightSpec = EstimateSpec.getSizeWithMode(height - weekBarHeight - mDelegate.getCalendarItemHeight(),
                    EstimateSpec.PRECISE);
            mContentView.setWidth(widthMeasureSpec);
            mContentView.setHeight(heightSpec);
            return false;
        }

        if (monthHeight >= height && mMonthView.getHeight() > 0) {
            height = monthHeight;
            heightMeasureSpec = EstimateSpec.getSizeWithMode(monthHeight +
                    weekBarHeight +
                    mDelegate.getWeekBarHeight(), EstimateSpec.PRECISE);
        } else if (monthHeight < height && mMonthView.getHeight() > 0) {
            heightMeasureSpec = EstimateSpec.getSizeWithMode(height, EstimateSpec.PRECISE);
        }

        int h;
        if (mCalendarShowMode == CALENDAR_SHOW_MODE_ONLY_MONTH_VIEW ||
                mCalendarView.getVisibility() == HIDE) {
            h = height - (mCalendarView.getVisibility() == HIDE ? 0 : mCalendarView.getHeight());
        } else if (mGestureMode == GESTURE_MODE_DISABLED && !isAnimating) {
            if (isExpand()) {
                h = height - monthHeight;
            } else {
                h = height - weekBarHeight - mItemHeight;
            }
        } else {
            h = height - weekBarHeight - mItemHeight;
        }
        super.setHeight(heightMeasureSpec);
        int heightSpec = EstimateSpec.getSizeWithMode(h,
                EstimateSpec.PRECISE);
        mContentView.setWidth(widthMeasureSpec);
        mContentView.setHeight(heightSpec);

        return false;
    }


    @Override
    public void onComponentBoundToWindow(Component component) {
        mMonthView = (MonthViewPager) findComponentById(ResourceTable.Id_vp_month);
        mWeekPager = (WeekViewPager) findComponentById(ResourceTable.Id_vp_week);
        if (getChildCount() > 0) {
            mCalendarView = (CalendarView) getComponentAt(0);
        }
        mContentView = (ComponentContainer) findComponentById(mContentViewId);
        mYearView = (YearViewPager) findComponentById(ResourceTable.Id_selectLayout);
    }

    @Override
    public void onComponentUnboundFromWindow(Component component) {

    }

    /**
     * 如果有十分特别的ContentView，可以自定义实现这个接口
     */
    public interface CalendarScrollView {
        /**
         * 是否滚动到顶部
         *
         * @return 是否滚动到顶部
         */
        boolean isScrollToTop();
    }
}
